package com.xbongbong.help.dynamic;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.field.LinkListPojo;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.TitleUtil;
import com.xbongbong.parent.factory.BusinessDynamicFactory;
import com.xbongbong.parent.interfaces.DynamicStrategy;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicAddLinkData;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author 吴峰
 * @date 2023/01/05 16:12
 */

@Slf4j
@Component
public class BusinessDynamicHelp  {
    public static final List<Integer> SHOW_DYNAMIC_BUSINESSTYPE_LIST = Arrays.asList(
            XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(),
            XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(),
            XbbRefTypeEnum.CONTACT.getCode(),
            XbbRefTypeEnum.CONTRACT.getCode(),
            XbbRefTypeEnum.WORK_ORDER_V2.getCode()
    );

    @Resource
    private UserModel userModel;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private BusinessDynamicFactory businessDynamicFactory;

    @Async("dynamicThreadPool")
    public void addLinkData(SaasFormSaveDTO saasFormSaveDTO){
        try{
            AtomicReference<UserEntity> processCreator = new AtomicReference<>();
            if (Objects.nonNull(saasFormSaveDTO.getProcessCreatorId())) {
                UserEntity userEntity = userModel.getByKeyIngoreDel(saasFormSaveDTO.getProcessCreatorId(), saasFormSaveDTO.getCorpid());
                processCreator.set(userEntity);
            }
            Integer isImport = saasFormSaveDTO.getIsImport();
            if(Objects.equals(isImport,1)){
                // 导入不加动态
                return;
            }
            String corpid = saasFormSaveDTO.getCorpid();
            JSONObject newData = saasFormSaveDTO.getNewData();
            Integer businessType = saasFormSaveDTO.getBusinessType();
            Integer saasMark = Objects.equals(businessType,0)? SaasMarkEnum.PAAS.getCode():SaasMarkEnum.SAAS.getCode();
            PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
            if(Objects.isNull(newPaasFormDataEntity)){
                newPaasFormDataEntity = getFormData(corpid,saasMark,businessType,saasFormSaveDTO.getDataId());
            }
            if(newPaasFormDataEntity==null){
                return;
            }
            Long dataId = newPaasFormDataEntity.getId();
            Long formId = newPaasFormDataEntity.getFormId();
            Map<String, FieldAttrEntity> explainMap = saasFormSaveDTO.getExplainMap();
            if(explainMap==null){
                PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, formId, businessType);
                explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
            }

            Set<String> set = new HashSet<>();
            Set<Long> formIds =  new HashSet<>();
            explainMap.forEach((attr, fieldAttrEntity) -> {
                Integer fieldType = fieldAttrEntity.getFieldType();
                if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType())) {
                    LinkInfoPojo linkInfo = fieldAttrEntity.getLinkInfo();
                    Integer linkBusinessType = linkInfo.getLinkBusinessType();
                    if(!SHOW_DYNAMIC_BUSINESSTYPE_LIST.contains(linkBusinessType)){
                        return;
                    }
                    formIds.add(linkInfo.getLinkFormId());
                }
            });

            Map<String, Object> param = new HashMap<>(2 << 1);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            param.put(ParameterConstant.ID_IN, formIds);
            List<PaasFormEntity> paasFormEntityList = paasFormModel.findEntity(param);
            Map<Long,Set<String>> associationMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            paasFormEntityList.forEach(item->{
                PaasFormEntity paasFormEntity = item;
                List<LinkListPojo> associationList = JSONArray.parseArray(paasFormEntity.getAssociationList(), LinkListPojo.class);
                if (Objects.isNull(associationList)) {
                    associationList = new ArrayList<>();
                }
                Set<String> associationSet = new HashSet<>();

                associationList.forEach(temp->{
                    Integer linkSaasMark = temp.getLinkSaasMark();
                    Integer linkBusinessType = temp.getLinkBusinessType();
                    if (Objects.equals(temp.getEnable(), 1)) {
                        StringBuilder sb = new StringBuilder();
                        sb.append(linkSaasMark).append(linkBusinessType).append(formId);
                        associationSet.add(sb.toString());
                    }
                });
                associationMap.put(item.getId(),associationSet);
            });
            PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId,corpid);
            Map<Integer,List<DynamicAddLinkData>> dataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            PaasFormDataEntityExt paasFormDataEntityExt = new PaasFormDataEntityExt(newPaasFormDataEntity.getId(), newPaasFormDataEntity.getCorpid(), newPaasFormDataEntity.getAppId(), newPaasFormDataEntity.getMenuId(), newPaasFormDataEntity.getFormId(), newPaasFormDataEntity.getSerialNo(), newPaasFormDataEntity.getOwnerId(), newPaasFormDataEntity.getDepartmentId(), newPaasFormDataEntity.getFlowStatus(), newPaasFormDataEntity.getData(), newPaasFormDataEntity.getCreatorId(), newPaasFormDataEntity.getAddTime(), newPaasFormDataEntity.getUpdateTime(), newPaasFormDataEntity.getDel());
            String name = TitleUtil.getTitle(businessType,paasFormEntityExt, explainMap, paasFormDataEntityExt);
            explainMap.forEach((attr, fieldAttrEntity)->{
                Integer fieldType = fieldAttrEntity.getFieldType();
                if(Objects.equals(fieldType,FieldTypeEnum.LINK_DATA.getType())){
                    LinkInfoPojo linkInfo = fieldAttrEntity.getLinkInfo();
                    Integer linkSaasMark = linkInfo.getLinkSaasMark();
                    Integer linkBusinessType = linkInfo.getLinkBusinessType();
                    Long linkFormId = linkInfo.getLinkFormId();
                    if(!SHOW_DYNAMIC_BUSINESSTYPE_LIST.contains(linkBusinessType)){
                        return;
                    }
                    StringBuilder key = new StringBuilder();
                    Long parentDataId = newData.getLong(attr);
                    if (Objects.equals(parentDataId, 0L) || Objects.isNull(parentDataId)) {
                        return;
                    }
                    key.append(linkSaasMark).append(linkBusinessType).append(parentDataId);

                    if(set.contains(key.toString())){
                        return;
                    }else {
                        set.add(key.toString());
                    }
                    StringBuilder sb = new StringBuilder();
                    sb.append(saasMark).append(businessType).append(formId);
                    Set<String> tempSet = associationMap.get(linkFormId);
                    if(!tempSet.contains(sb.toString())){
                        return;
                    }

                    DynamicAddLinkData dynamicAddLinkData = new DynamicAddLinkData();
                    if(Objects.nonNull(processCreator.get())){
                        UserEntity userEntity = processCreator.get();
                        dynamicAddLinkData.setUserName(userEntity.getName());
                        dynamicAddLinkData.setUserId(userEntity.getUserId());
                    } else {
                        dynamicAddLinkData.setUserName(saasFormSaveDTO.getLoginUserName());
                        dynamicAddLinkData.setUserId(saasFormSaveDTO.getUserId());
                    }
                    dynamicAddLinkData.setDataId(dataId);
                    dynamicAddLinkData.setFormId(formId);

                    dynamicAddLinkData.setName(name);
                    dynamicAddLinkData.setCorpid(corpid);
                    dynamicAddLinkData.setParentDataId(parentDataId);
                    dynamicAddLinkData.setParentBusinessType(linkBusinessType);
                    dynamicAddLinkData.setBusinessType(businessType);
                    dynamicAddLinkData.setAddNewData(newData);
                    if(dataMap.containsKey(linkBusinessType)){
                        List<DynamicAddLinkData> list = dataMap.get(linkBusinessType);
                        list.add(dynamicAddLinkData);
                    }else{
                        List<DynamicAddLinkData> list = new ArrayList();
                        list.add(dynamicAddLinkData);
                        dataMap.put(linkBusinessType,list);
                    }
                }
            });
            dataMap.forEach(( linkBusinessType,list)->{
                DynamicStrategy dynamicStrategy = businessDynamicFactory.getDynamicStrategyByBusinessType(linkBusinessType);
                if (Objects.nonNull(dynamicStrategy)) {
                    dynamicStrategy.addLinkData(list);
                } else {
                    businessDynamicFactory.getDynamicStrategyByBusinessType(null).addLinkData(list);
                }
            });

        }catch (XbbException e){
            log.warn("com.xbongbong.paas.service.dynamic.help.DynamicHelp.addLinkData",e);
        }catch (Exception e){
            log.error("com.xbongbong.paas.service.dynamic.help.DynamicHelp.addLinkData",e);
        }
    }

    public PaasFormDataEntityExt getFormData(String corpid, Integer saasMark, Integer businessType, Long dataId) throws XbbException {
        return null;
    }
}
